package com.iiitb.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.iiitb.wtp.URLConnect;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

public class SeedHandler {

	ArrayList<String> urlList = new ArrayList<String>();
	Map<String, String> urlLinks = new HashMap<>();

	Connection conn = null;
	String dbUrl = "jdbc:mysql://localhost:3306/";
	String dbName = "imagedb";
	String driver = "com.mysql.jdbc.Driver";
	String userName = "root";
	String password = "root";

	public Map<String, String> getUrlLinks() {
		return urlLinks;
	}

	public void setUrlLinks(Map<String, String> urlLinks) {
		this.urlLinks = urlLinks;
	}

	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}

	public String getDbUrl() {
		return dbUrl;
	}

	public void setDbUrl(String dbUrl) {
		this.dbUrl = dbUrl;
	}

	public String getDbName() {
		return dbName;
	}

	public void setDbName(String dbName) {
		this.dbName = dbName;
	}

	public String getDriver() {
		return driver;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public List<String> getUrlList() {
		return urlList;
	}

	public void setUrlList(ArrayList<String> urlList) {
		this.urlList = urlList;
	}

	// Add content to urlList
	public void addUrlList(String url) {
		urlList.add(url);
	}

	// Constructor: connects to database and loads the seed's (URL's) from the
	// database.
	public SeedHandler() throws SQLException {
		connectDatabase();
		// loadData(conn);
	}

	// Connects to the database
	private void connectDatabase() {

		try {
			Class.forName(getDriver()).newInstance();
			conn = DriverManager.getConnection(getDbUrl() + getDbName(),
					getUserName(), getPassword());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void mainCrawler() {

		URLConnect connector = new URLConnect(urlLinks);

		System.out.println("connected to all pages!!");
	}

	public String mainCrawler(Map<String, String> parseTag) {

		URLConnect connector = new URLConnect(parseTag);
		String tag = connector.getTag();
		// System.out.println("connected to all pages!!");
		return tag;
	}

	// Closing the database.
	public void closeDatabase(Connection conn) throws SQLException {
		conn.close();
	}

	// Loads the urlList variable the the seeds(URLs) from database.
	public void loadData() throws SQLException {
		Statement stmt = null;
		ResultSet rs = null;

		stmt = conn.createStatement();
		System.out.println("Started loading the data from database!");

		if (stmt.execute("SELECT * FROM seed_list;")) {
			rs = stmt.getResultSet();
		} else {
			System.err.println("select failed");
		}

		while (rs.next()) {
			urlLinks.put(rs.getString(2), rs.getString(3));
		}

	}

	public String queryData(String queryURL, String method) throws SQLException {
		Statement stmt = null;
		ResultSet rs = null;
		String query = "";
		stmt = conn.createStatement();
		System.out.println("Querying the database");
		if (method.equals("HITS")) {
			query = "select tag from HITS where hyperlink =\"" + queryURL
					+ "\"";
		} else if (method.equals("PageRank")) {
			query = "select tag from PageRank where hyperlink =\"" + queryURL
					+ "\"";
		}
		if (stmt.execute(query)) {
			rs = stmt.getResultSet();
		} else {
			System.err.println("select failed");
		}
		String tag = "";
		while (rs.next()) {
			tag = tag + rs.getString(1);
		}

	
		return tag;

	}

	// Inserts the seed(URL)'s into database
	public void insertData(String userUrl, String tag) throws SQLException {
		try {
			ResultSet rs = null;
			Statement stmt = conn.createStatement();
			String selectQuery = "select tag from seed_list where url = \""
					+ userUrl + "\"";
			if (stmt.execute(selectQuery)) {
				rs = stmt.getResultSet();
			} else {
				System.err.println("select failed");
			}
			String tagDB = "";
			while (rs.next()) {
				tagDB = tagDB + rs.getString(1);
			}
			String tagUpdate = "";
			if (tagDB.equalsIgnoreCase(tag)) {
				tagUpdate = tagDB;
			} else {
				tagUpdate = tagDB + ", " + tag;
			}
			String sql = "INSERT INTO seed_list(url, tag) VALUES(?,?) on duplicate key update tag = \""
					+ tagUpdate + "\"";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, userUrl);
			pstmt.setString(2, tag);
			pstmt.executeUpdate();

			// Also keep the url in the arraylist
			urlLinks.put(userUrl, tagUpdate);
		} catch (MySQLIntegrityConstraintViolationException e) {
			e.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}

	// Inserts the searched_url table data into database
	public void insertSearchedData(String userUrl, String tag)
			throws SQLException {
		try {
			ResultSet rs = null;
			Statement stmt = conn.createStatement();
			String selectQuery = "select category from searched_url where hyperlink = \""
					+ userUrl + "\"";
			if (stmt.execute(selectQuery)) {
				rs = stmt.getResultSet();
			} else {
				System.err.println("select failed");
			}
			String tagDB = "";
			while (rs.next()) {
				tagDB = tagDB + rs.getString(1);
			}
			String tagUpdate = "";
			if (tagDB.equalsIgnoreCase(tag)) {
				tagUpdate = tagDB;
			} else {
				tagUpdate = tagDB + ", " + tag;
			}
			String sql = "INSERT INTO searched_url(hyperlink, category) VALUES(?, ?) on duplicate key update category =\""
					+ tagUpdate + "\"";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, userUrl);
			pstmt.setString(2, tag);
			pstmt.executeUpdate();

		} catch (MySQLIntegrityConstraintViolationException e) {
			e.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	// Inserts the HITS data into database
	public void insertHITSData(String userUrl, Double authScore,
			Double hubScore, String tag) throws SQLException {

		try {
			String sql = "INSERT INTO HITS(hyperlink, authScore, hubScore, tag) VALUES(?, ?, ?, ?) on duplicate key update authScore="
					+ authScore + ",hubScore=" + hubScore;
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, userUrl);
			pstmt.setDouble(2, authScore);
			pstmt.setDouble(3, hubScore);
			pstmt.setString(4, tag);
			pstmt.executeUpdate();
		} catch (MySQLIntegrityConstraintViolationException e) {
			e.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}

	// Inserts the PageRank data into database
	public void insertPGData(String userUrl, Double score, String tag)
			throws SQLException {

		try {
			if (score == Double.POSITIVE_INFINITY || score == Double.NaN)
				score = -1.0;
			String sql = "INSERT INTO PageRank(hyperlink, scores, tag) VALUES(?, ?, ?) on duplicate key update scores ="
					+ score;

			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, userUrl);
			pstmt.setDouble(2, score);
			pstmt.setString(3, tag);
			pstmt.executeUpdate();
		} catch (MySQLIntegrityConstraintViolationException e) {
			e.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}

}
